use axum::body::{to_bytes, Body, Bytes};
use axum::extract::Request;
use axum::http::Method;
use axum::middleware::Next;
use axum::response::Response;
use log::info;

/// 打印接口参数
pub async fn print_params(mut req: Request, next: Next) -> Response {
    let method = req.method();
    if let &Method::GET = method {
        let query = req.uri().query();
        if query.is_some() {
            info!("查询参数: {}", query.unwrap());
        }
        return next.run(req).await;
    }

    if is_json_content(&req) || is_form_content(&req) {
        let (parts, body) = req.into_parts();
        let bytes = to_bytes(body, usize::MAX)
            .await
            .unwrap_or_else(|_| Bytes::new());

        let v = bytes.to_vec();

        // let body_str = unsafe { String::from_utf8_unchecked(v) };
        let body_str = String::from_utf8_lossy(v.as_slice());
        if !body_str.is_empty() {
            info!("请求参数: {}", body_str);
        }
        // 重新构建body供后续使用
        req = Request::from_parts(parts, Body::from(bytes));
    }

    next.run(req).await
}

/// 检查是否JSON内容类型
fn is_json_content<B>(req: &Request<B>) -> bool {
    req.headers()
        .get("Content-Type")
        .map(|v| v.as_bytes().starts_with(b"application/json"))
        .unwrap_or(false)
}

/// 检查是否FORM内容类型
fn is_form_content<B>(req: &Request<B>) -> bool {
    req.headers()
        .get("Content-Type")
        .map(|v| {
            v.as_bytes()
                .starts_with(b"application/x-www-form-urlencoded")
        })
        .unwrap_or(false)
}
